#include "hal_rtc_device.h"

#include <HardwareSerial.h>
#include <M5EPD.h>

HalRtcDevice::HalRtcDevice(BM8563& dev) : _devHandle(dev) {}

bool HalRtcDevice::GetDate(Date& date) {
  rtc_date_t rtcDate;
  _devHandle.getDate(&rtcDate);

  date.year = rtcDate.year;
  date.mon = rtcDate.mon;
  date.day = rtcDate.day;
  date.week = rtcDate.week;
  Serial.printf("RTC get date success: %d/%d/%d %d!\r\n", date.year, date.mon,
                date.day, date.week);
  return true;
}

bool HalRtcDevice::GetTime(Time& time) {
  rtc_time_t rtcTime;
  _devHandle.getTime(&rtcTime);

  time.hour = rtcTime.hour;
  time.min = rtcTime.min;
  time.sec = rtcTime.sec;
  Serial.printf("RTC get time success: %d:%d:%d!\r\n", time.hour, time.min,
                time.sec);
  return true;
}

bool HalRtcDevice::SetDate(const Date& date) {
  rtc_date_t rtcDate;
  rtcDate.year = date.year;
  rtcDate.mon = date.mon;
  rtcDate.day = date.day;
  rtcDate.week = date.week;

  // BM8563::setDate 成功返回1，失败返回0
  if (!_devHandle.setDate(&rtcDate)) {
    Serial.println("RTC set date failed!");
    return false;
  }
  Serial.printf("RTC set date success: %d/%d/%d %d!\r\n", date.year, date.mon,
                date.day, date.week);
  return true;
}

bool HalRtcDevice::SetTime(const Time& time) {
  rtc_time_t rtct;
  rtct.hour = time.hour;
  rtct.min = time.min;
  rtct.sec = time.sec;

  // BM8563::setTime 成功返回1，失败返回0
  if (!_devHandle.setTime(&rtct)) {
    Serial.println("RTC set time failed!");
    return false;
  }
  Serial.printf("RTC set time success: %d:%d:%d\r\n", time.hour, time.min,
                time.sec);
  return true;
}

bool HalRtcDevice::ConvertDateTime(Date& date, Time& time, time_t timestamp) {
  struct tm* tmPtr = gmtime(&timestamp);
  if (!tmPtr) {
    return false;
  }
  date.year = tmPtr->tm_year + 1900;  // 1900 为基础的年数
  date.mon = tmPtr->tm_mon + 1;       // 0~11
  date.day = tmPtr->tm_mday;
  date.week = tmPtr->tm_wday;  // 0~6 ， 0 是星期日

  time.hour = tmPtr->tm_hour;
  time.min = tmPtr->tm_min;
  time.sec = tmPtr->tm_sec;

  return true;
}
